/***************************************************************************************
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
*
* NEMU is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*          http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/

#include <isa.h>
#include <cpu/difftest.h>
#include <memory/paddr.h>
#include "../local-include/reg.h"

#define DIFFTEST_CHECK_CSR(reg)	 if (ref_r->csr.reg.value != cpu.csr.reg.value) { difftest_check_reg(#reg, pc, ref_r->csr.reg.value, cpu.csr.reg.value); success = false; }

bool isa_difftest_checkregs(CPU_state *ref_r, vaddr_t pc) {
    bool success = true;

    // CHECK regs
    for (int i = 0; i < ARRLEN(cpu.gpr); ++i) {
        if (ref_r->gpr[i] == cpu.gpr[i]) continue;
        difftest_check_reg(reg_name(i), pc, ref_r->gpr[i], cpu.gpr[i]);
        success = false;
    }
    
    // CHECK pc
    if (ref_r->pc != cpu.pc) {
        difftest_check_reg("pc", pc, ref_r->pc, cpu.pc);
        success = false;
    }
    
    // CHECK csrs
    DIFFTEST_CHECK_CSR(mstatus);
    DIFFTEST_CHECK_CSR(mie);
    DIFFTEST_CHECK_CSR(mtvec);
    DIFFTEST_CHECK_CSR(mepc);
    DIFFTEST_CHECK_CSR(mcause);
    // DIFFTEST_CHECK_CSR(mip);

    return success;
}

void isa_difftest_attach() {
    // 将 DUT 的 guest memory 拷贝到 REF 中
    ref_difftest_memcpy(RESET_VECTOR, guest_to_host(RESET_VECTOR), CONFIG_MSIZE, DIFFTEST_TO_REF);
    // 将 DUT 的寄存器的初始状态拷贝到 REF 中
    ref_difftest_regcpy(&cpu, DIFFTEST_TO_REF);
}
